home *** CD-ROM | disk | FTP | other *** search
- ;
- ; interrupt wrapping routines; these should just save registers and call
- ; the appropriate C handlers, unless speed is a major problem
- ;
- ; $Log: intr.s,v $
- ; Revision 1.5 1992/04/18 10:57:18 AGK
- ; More +8s for 0.94
- ;
- ; Revision 1.4 1992/04/04 16:05:54 AGK
- ; Added some missing +8s in the vector pushes to allow for XBRA support
- ;
- ; Revision 1.3 1992/03/31 14:02:08 AGK
- ; Fixed for real Motorola syntax (many thanks to ERS for keeping these
- ; files in step with the GAS ones).
- ;
- ; Revision 1.2 1992/03/31 13:55:28 AGK
- ; Checked in MiNT 0.93 sources
- ;
- ; Revision 1.1 1991/05/30 17:22:18 AGK
- ; Initial revision
- ;
- SECTION TEXT
- ;
- ; first, utilities for setting processor status level
- ;
- XDEF _spl7,_spl
- _spl7:
- move.w sr,d0
- ori.w #$0700,sr
- rts
- _spl:
- move.w 4(sp),d0
- move.w d0,sr
- rts
-
- XDEF _mint_5ms
- XDEF _mint_timer
- XDEF _mint_vbl
- XREF _timeout ; C time routine
- XREF _old_timer ; old GEMDOS time vector
- XREF _old_vbl ; old GEMDOS vbl vector
- XREF _old_5ms
- XREF _build_context
- XREF _restore_context
- XREF _proc_clock ; controls process' allocation of CPU time
- XREF _curproc
- XREF _enter_kernel
- XREF _leave_kernel
- XREF _preempt
- XREF _in_kernel
-
- ; AKP: this code is hit once every 5ms; it updates the time fields of curproc.
- _mint_5ms:
- move.l a0,-(sp)
- move.l _curproc,a0
- add.w #$364,a0 ; $364 is offset to curproc->systime;
- tst.w _in_kernel
- bne L_5a ; usrtime is the branch-not-taken case
- addq.l #4,a0
- L_5a: addq.l #5,(a0)
- move.l (sp)+,a0
- move.l _old_5ms+8,-(sp)
- rts
-
- _mint_timer:
- movem.l d0-d2/a0-a2,-(sp) ; save C registers
- jsr _timeout
- movem.l (sp)+,d0-d2/a0-a2
- move.l _old_timer+8,-(sp) ; jump to GEMDOS time vector
- rts
-
- _mint_vbl:
- tst.w ($59e).w ; test longframe (AKP)
- beq.s L_short1
- clr.w -(sp) ; yes, long frames: push a frame word
- L_short1:
- pea L_comeback ; push fake PC
- move.w sr,-(sp) ; push status register
- move.l _old_vbl+8,-(sp) ; go service the interrupt
- rts
-
- L_comeback:
- tst.w _proc_clock ; has time expired yet?
- beq.s L_expired ; yes -- maybe go switch processes
- L_out:
- rte ; no -- just return
-
- L_expired:
- btst #13,(sp) ; user mode?
- bne.s L_out ; no -- switching is not possible
- L_switch:
- move.l _curproc,-(sp)
- addq.l #4,(sp) ; to get &curproc->ctxt[SYSCALL]
- jsr _build_context ; build context
- move.l _curproc,a0
- move.l (a0),sp ; use curproc->sysstack
- jsr _enter_kernel ; enter kernel
- jsr _preempt ; yield processor
- ori.w #$700,sr ; spl7()
- jsr _leave_kernel ; restore vectors
- move.l _curproc,a0
- pea 4(a0)
- jsr _restore_context ; back to user
-
- ;
- ; reset routine -- called on a warm boot. Note that TOS sends the
- ; address to which we should return in register a6. Also note that
- ; the stack pointer is in an unknown state, so we set up our own
- ;
- XDEF _reset
- XREF _tmpstack ; see main.c
- XREF _restr_intr
-
- _reset:
- move.w #$2700,sr ; avoid interruption here
- move.l sp,_tmpstack ; save A7
- lea _tmpstack,sp ; set up temporary stack
- lea 256(sp),sp
- movem.l d0-d2/a0-a2,-(sp) ; save C registers
- jsr _restr_intr ; restore interrupts
- movem.l (sp)+,d0-d2/a0-a2 ; restore registers
- move.l _tmpstack,sp
- jmp (a6) ; reset again
-
- ;
- ; routine for doing a reboot
- ;
- XDEF _reboot
- _reboot:
- move.w #$2700,sr ; avoid interrupts
- move.l (0).w,sp ; get sp after reboot
- move.l (4).w,a6 ; get new reboot address
- jmp _reset
-
- ;
- ; routine for mouse packet handling
- ;
- XDEF _newmvec
- XREF _mouse_handler
-
- _newmvec:
- move.l a0,-(sp)
- jsr _mouse_handler
- move.l (sp)+,a0
- rts
-
- ;
- ; new ikbd keyboard interrupt vector
- ; kintr is a global variable that should be non-zero if a keyboard
- ; event occured
- ;
- XDEF _new_ikbd
- XREF _old_ikbd
- XREF _kintr
-
- _new_ikbd:
- move.w #1,_kintr
- move.l _old_ikbd+8,-(sp)
- rts ; jump to system interrupt routine
-
- ;
- ; simple signal handlers
- ; global variables referenced:
- ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
- ; sig_routine: (signal.c): pointer to which signal catching routine to
- ; call (e.g. for SIGBUS, or whatever)
- ;
- XDEF _new_bus,_new_addr,_new_ill,_new_divzero,_new_priv
- XDEF _new_trace
- XREF _in_kernel,_sig_routine
- XREF _sigbus,_sigaddr,_sigill,_sigfpe,_sigpriv,_sigtrap
-
- _new_bus:
- move.l #_sigbus,_sig_routine
- Do_sig:
- tst.w _in_kernel ; are we already in the kernel?
- bne.s Kernel ; yes
- move.l _curproc,-(sp)
- add.l #4,(sp) ; push offset of save area
- jsr _build_context
- move.l _curproc,a4
- move.l (a4),sp ; put us in the system stack
- jsr _enter_kernel ; set up kernel vectors
- move.l _sig_routine,a1 ; get signal handling routine
- jsr (a1) ; go do it
- ori.w #$0700,sr ; spl7()
- jsr _leave_kernel ; leave kernel
- lea 4(a4),a4 ; get context save area address
- move.l a4,-(sp) ; push it
- jsr _restore_context ; restore the context
- ;
- ; here's what we do if we already were in the kernel
- ;
- Kernel:
- movem.l d0-d2/a0-a2,-(sp) ; save reggies
- move.l _sig_routine,a1 ; get handler
- jsr (a1) ; go do it
- movem.l (sp)+,d0-d2/a0-a2
- rte
- _new_addr:
- move.l #_sigaddr,_sig_routine
- bra.s Do_sig
- _new_ill:
- move.l #_sigill,_sig_routine
- bra.s Do_sig
- _new_divzero:
- move.l #_sigfpe,_sig_routine
- bra.s Do_sig
- _new_priv:
- move.l #_sigpriv,_sig_routine
- bra Do_sig
- _new_trace:
- move.l #_sigtrap,_sig_routine
- bra Do_sig
-
- ;
- ; BIOS disk vectors for pseudo-disks like U: and X:; these are present
- ; just in case some program (foolishly) attempts to access these drives
- ; directly and gets horribly confused
- ;
- XREF _old_getbpb ; old Getbpb vector
- XREF _old_mediach ; old Mediach vector
- XREF _old_rwabs ; old Rwabs vector
- XDEF _new_getbpb
- XDEF _new_mediach
- XDEF _new_rwabs
-
- _new_getbpb:
- move.w 4(sp),d0 ; check the drive
- cmp.w #$10,d0 ; drive Q:?
- beq.s nobpb ; yes, no BPB available
- cmp.w #$14,d0 ; drive U:?
- beq.s nobpb ; yes, no BPB available
- cmp.w #$15,d0 ; drive V:?
- beq.s nobpb
- cmp.w #$17,d0 ; drive X:?
- beq.s nobpb
- move.l _old_getbpb+8,a0 ; not our drive
- jmp (a0) ; call the old vector for it
- nobpb:
- moveq.l #0,d0 ; 0 means "no BPB read"
- rts
-
- _new_mediach:
- move.w 4(sp),d0 ; check the drive
- cmp.w #$10,d0 ; drive Q:?
- beq.s nochng ; yes, no change
- cmp.w #$14,d0 ; drive U:?
- beq.s nochng ; yes, no change
- cmp.w #$15,d0 ; drive V:?
- beq.s nochng
- cmp.w #$17,d0 ; drive X:?
- beq.s nochng
- move.l _old_mediach+8,a0 ; not our drive
- jmp (a0) ; call the old vector for it
- nochng:
- moveq.l #0,d0 ; 0 means "definitely no change"
- rts
-
- _new_rwabs:
- move.w $e(sp),d0 ; check the drive
- cmp.w #$10,d0 ; drive Q:?
- beq.s rwdone ; yes, fake a successful I/O operation
- cmp.w #$14,d0 ; drive U:?
- beq.s rwdone ; yes, fake it
- cmp.w #$15,d0 ; drive V:?
- beq.s rwdone
- cmp.w #$17,d0 ; drive X:?
- beq.s rwdone
- move.l _old_rwabs+8,a0 ; not our drive
- jmp (a0) ; call the old vector for it
- rwdone:
- moveq.l #0,d0 ; 0 means "successful operation"
- rts
-
- END
-